/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 2008-2009, The KiWi Project (http://www.kiwi-project.eu)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice, 
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice, 
 *   this list of conditions and the following disclaimer in the documentation 
 *   and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Contributor(s):
 * 
 * 
 */
package kiwi.core.model.rdf;

import kiwi.core.model.Constants;
import kiwi.core.model.annotations.RDF;
import kiwi.core.model.user.KiWiUser;
import org.hibernate.annotations.*;
import org.hibernate.annotations.Cache;

import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.util.Date;


/**
 * KiWiNode is the base class of all objects stored in the knowledge base. The relevant subclasses 
 * are KiWiResource and KiWiLiteral.
 * <p/>
 * The KiWiNode entity represents common properties of nodes like the creation and modification dates, the
 * creator, and the context.
 * * 
 * @author sschaffe
 * @see kiwi.core.api.triplestore.TripleStore
 */
@Entity
@Immutable
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "nodetype", discriminatorType = DiscriminatorType.STRING )
@org.hibernate.annotations.Entity(optimisticLock=OptimisticLockType.VERSION)
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@BatchSize(size = 100)
@NamedQueries({
	@NamedQuery(name  = "tripleStore.markDeleted",
				query = "update KiWiNode n " +
				        "set n.deleted = true "+
						"where n.id = :id"),
    @NamedQuery(name  = "tripleStore.markUndeleted",
                query = "update KiWiNode n " +
                        "set n.deleted = false "+
                        "where n.id = :id")
})
public abstract class KiWiNode implements Serializable {
    
	/**
	 * 
	 */
	private static final long serialVersionUID = 4652575123005436645L;

    /**
     * Unique ID of the KiWiNode in the database. This ID should not be exposed to the outside, it may be
     * different between different KiWi installations.
     */
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;


    /**
     * The creation date of the KiWiNode.
     **/
    @Temporal(value = TemporalType.TIMESTAMP)
    @Column(updatable = false, nullable=false)
    @RDF(Constants.NS_KIWI_CORE+"createdOn")
    private Date created;

    /** The KnowledgeSpace the content item belongs to */
    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @LazyToOne(LazyToOneOption.FALSE)
    @Immutable
    private KiWiUriResource context;


    /** the user who created this KiWi Resource */
    @ManyToOne(fetch=FetchType.EAGER)
    @RDF(Constants.NS_KIWI_CORE+"author")
    private KiWiUser creator;



    private boolean deleted;

    
	@Version
	private Long version;


    @Transient
    private String creatorTransactionId;


    protected KiWiNode() {
        this.created   = new Date();
        this.deleted   = false;
    }


    protected KiWiNode(KiWiUser creator) {
        this();
        this.creator = creator;
    }

    /**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}


	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

    /**
     * Return the KnowledgeSpace (a KiWiUriResource) this ContentItem belongs to.
     * @return
     */
    public KiWiUriResource getContext() {
        return context;
    }

    /**
     * Set the KnowledgeSpace (a KiWiUriResource) this ContentItem belongs to.
     * @param context
     */
    public void setContext(KiWiUriResource context) {
        this.context = context;
    }


    /**
     * @return the created
     */
    public Date getCreated() {
        return created;
    }

    /**
     * @param created the created to set
     */
    public void setCreated(Date created) {
        this.created = created;
    }


    /**
     * @return the deleted
     */
    public boolean isDeleted() {
        return deleted;
    }

    /**
     * @param deleted the deleted to set
     */
    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }




	public abstract String getCacheKey();
	
    
    public abstract boolean isUriResource();
    
    public abstract boolean isAnonymousResource();
    
    public abstract boolean isLiteral();
    
    public abstract String getShortName()  throws URISyntaxException;


    /**
     * Return a representation of the node in TURTLE syntax.
     *
     * http://www.w3.org/TeamSubmission/turtle/
     *
     * @return
     */
    public abstract String toTurtle();


    /**
     * Return a representation of the node in RDF/JSON syntax.
     *
     * http://n2.talis.com/wiki/RDF_JSON_Specification
     * @param asObject indicates whether formatting should be as object (i.e. with additional type information)
     * @return
     */
    public abstract String toJSON(boolean asObject);

    /**
     * @return the author
     */
    public KiWiUser getCreator() {
        return creator;
    }

    /**
     * @param author the author to set
     */
    public void setCreator(KiWiUser author) {
        this.creator = author;
    }






    /**
	 * @return the version
	 */
	public Long getVersion() {
		return version;
	}


	/**
	 * @param version the version to set
	 */
	public void setVersion(Long version) {
		this.version = version;
	}


    public String getCreatorTransactionId() {
        return creatorTransactionId;
    }

    public void setCreatorTransactionId(String creatorTransactionId) {
        this.creatorTransactionId = creatorTransactionId;
    }
}
